package com.example.fabric1.controller;

import com.example.fabric1.controller.request.CodeDMRequest;
import com.example.fabric1.model.code.CodeDMInfo;
import com.example.fabric1.model.code.DeliveryItem;
import com.example.fabric1.model.code.PickItem;
import com.example.fabric1.model.code.VerifierItem;
import com.example.fabric1.util.JsonData;
import com.example.fabric1.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.hyperledger.fabric.gateway.Contract;
import org.hyperledger.fabric.gateway.ContractException;
import org.hyperledger.fabric.gateway.Network;
import org.hyperledger.fabric.gateway.Transaction;
import org.hyperledger.fabric.sdk.Peer;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeoutException;

@Slf4j
@RestController
@RequestMapping("/api/v1/trace/codeDM")
public class CodeDMController {
    @Resource
    private Contract contract;

    @Resource
    private Network network;

    @GetMapping("/query")
    public JsonData query(String code) throws ContractException {
        String chainFuncName = "QueryData";
        if (code == null) {
            return JsonData.buildError("参数不能为空");
        }
        byte[] codeInfo = contract.evaluateTransaction("Invoke", chainFuncName, code);
        CodeDMInfo result = JsonUtil.bytes2Obj(codeInfo, CodeDMInfo.class);
        return JsonData.buildSuccess(result);
    }

    @PostMapping("/uploadCode")
    public JsonData uploadCode(String code, @RequestBody CodeDMRequest codeInfo) throws ContractException, InterruptedException, TimeoutException {
        Transaction transaction = contract.createTransaction("Invoke")
                .setEndorsingPeers(network.getChannel().getPeers(EnumSet.of(Peer.PeerRole.ENDORSING_PEER)));
        String chainFuncName = "UploadCodeDM";
        if (code == null || codeInfo == null) {
            return JsonData.buildError("参数不能为空");
        }
        byte[] result = transaction.submit(chainFuncName, code, JsonUtil.obj2Json(codeInfo.getOrderInfo()),
                JsonUtil.obj2Json(codeInfo.getBusinessInfo()));

        Map<String, Object> map = new HashMap<>(2);
        map.put("txId", transaction.getTransactionId());
        map.put("data", new String(result));
        return JsonData.buildSuccess(map);
    }

    @PostMapping("/addPickInfo")
    public JsonData addPickInfo(String code, @RequestBody PickItem pickInfo) throws ContractException, InterruptedException, TimeoutException {
        Transaction transaction = contract.createTransaction("Invoke")
                .setEndorsingPeers(network.getChannel().getPeers(EnumSet.of(Peer.PeerRole.ENDORSING_PEER)));
        String chainFuncName = "AddPickInfoDM";
        if (code == null || pickInfo == null) {
            return JsonData.buildError("参数不能为空");
        }
        byte[] result = transaction.submit(chainFuncName, code, JsonUtil.obj2Json(pickInfo));

        Map<String, Object> map = new HashMap<>(2);
        map.put("txId", transaction.getTransactionId());
        map.put("data", new String(result));
        return JsonData.buildSuccess(map);
    }

    @PostMapping("/addDeliveryInfo")
    public JsonData addDeliveryInfo(String code, @RequestBody DeliveryItem deliveryInfo) throws ContractException, InterruptedException, TimeoutException {
        Transaction transaction = contract.createTransaction("Invoke")
                .setEndorsingPeers(network.getChannel().getPeers(EnumSet.of(Peer.PeerRole.ENDORSING_PEER)));
        String chainFuncName = "AddDeliveryInfoDM";
        if (code == null || deliveryInfo == null) {
            return JsonData.buildError("参数不能为空");
        }
        byte[] result = transaction.submit(chainFuncName, code, JsonUtil.obj2Json(deliveryInfo));

        Map<String, Object> map = new HashMap<>(2);
        map.put("txId", transaction.getTransactionId());
        map.put("data", new String(result));
        return JsonData.buildSuccess(map);
    }

    @PostMapping("/addVerifyInfo")
    public JsonData addVerifyInfo(String code, @RequestBody VerifierItem verifierInfo) throws ContractException, InterruptedException, TimeoutException {
        Transaction transaction = contract.createTransaction("Invoke")
                .setEndorsingPeers(network.getChannel().getPeers(EnumSet.of(Peer.PeerRole.ENDORSING_PEER)));
        String chainFuncName = "AddVerifyInfoDM";
        if (code == null || verifierInfo == null) {
            return JsonData.buildError("参数不能为空");
        }
        byte[] result = transaction.submit(chainFuncName, code, JsonUtil.obj2Json(verifierInfo));

        Map<String, Object> map = new HashMap<>(2);
        map.put("txId", transaction.getTransactionId());
        map.put("data", new String(result));
        return JsonData.buildSuccess(map);
    }
}
